package org.handsomeking.mincroservice.nacos.config;

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.boot.SpringBootConfiguration;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/***
 * @author gaoqijin
 * @date 2021-6-16
 * @Description
 */
@SpringBootConfiguration
public class SentinelConfig {



    @PostConstruct
    void initConfig(){
        System.out.println("initConfig");
        initFlowRule();
        initCircuitBreaker();
    }

    /**
     * 热点key:ParamFlowRule
     * https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81
     */
    private void initCircuitBreaker(){
        List<DegradeRule> rules =  new ArrayList<>();
        rules.add(degradeRule1());
        DegradeRuleManager.loadRules(rules);
    }

    /**
     * 降级1
     * 资源：/sentinel/testA
     * 熔断策略：慢调用比例
     * 最大RT：200ms
     * 比例阈值：0.5
     * 熔断时长：10s
     * 最小请求数：10
     */
    private DegradeRule degradeRule1() {
        DegradeRule degradeRule = new DegradeRule();
        degradeRule.setResource("/sentinel/testA");
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        degradeRule.setCount(200);
        degradeRule.setSlowRatioThreshold(0.5);
        degradeRule.setTimeWindow(10);
        degradeRule.setMinRequestAmount(10);
        return degradeRule;
    }

    /**
     * 限流配置
     */
    private void initFlowRule(){
        List<FlowRule> rules = new ArrayList<>();
        rules.add(rule1());
        rules.add(rule2());
        rules.add(rule3());
        rules.add(rule4());
        FlowRuleManager.loadRules(rules);
    }
    /**
     * 资源：/sentinel/testA
     * 针对来源：default
     * 阈值类型：QPS
     * 单机阈值：2
     * 集群模式：否
     * 流控模式：直接
     * 流控效果：快速失败
     */
    private FlowRule rule1 (){
        FlowRule rule = new FlowRule();
        rule.setResource("sentinel/testA");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(1);
        return rule;
    }
    /**
     * 资源：/sentinel/testB
     * 针对来源：default
     * 阈值类型：QPS
     * 单机阈值：2
     * 集群模式：否
     * 流控模式：直接
     * **** 流控效果：预热 ***
     * **** 流控效果：预热时长：10s ***
     *
     */
    private FlowRule rule2 (){
        FlowRule rule = new FlowRule();
        rule.setResource("/sentinel/testB");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(20);
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
        // 单位：秒
        rule.setWarmUpPeriodSec(10);
        return rule;
    }
    /**
     * 资源：/sentinel/testC
     * 针对来源：default
     * 阈值类型：QPS
     * 单机阈值：2
     * 集群模式：否
     * *** 流控模式：关联 ***
     * *** 流控模式：关联资源：rule1 ***
     * 流控效果：快速失败
     */
    private FlowRule rule3 (){
        FlowRule rule = new FlowRule();
        rule.setResource("/sentinel/testC");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(2);
        rule.setStrategy(RuleConstant.STRATEGY_RELATE);
        rule.setRefResource("/sentinel/testA");
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
        return rule;
    }
    /**
     * 资源：/sentinel/testD
     * 针对来源：default
     * 阈值类型：THREAD
     * 单机阈值：2
     * 集群模式：否
     * 流控模式：直接
     * 流控效果：快速失败
     */
    private FlowRule rule4 (){
        FlowRule rule = new FlowRule();
        rule.setResource("/sentinel/testD");
        rule.setGrade(RuleConstant.FLOW_GRADE_THREAD);
        // Set limit thread to 2.
        rule.setCount(2);
        return rule;
    }
}
